package com.windystory.wslibrary.service;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.GpsSatellite;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import androidx.core.app.ActivityCompat;
import android.text.TextUtils;
import com.windystory.wslibrary.util.LogUtil;
import com.windystory.wslibrary.util.PrefUtil;
import com.windystory.wslibrary.util.event.Event;

import org.greenrobot.eventbus.EventBus;

import java.util.Date;
import java.util.Iterator;

/**
 * GPS定位
 *
 * @author hhz
 */

public class GpsService extends Service {
    final static String TAG = "GpsService";

    boolean isBroadcastToOtherApp = false;//位置实时更新时，是否给其他应用广播位置信息

    public GpsService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO: 2016/12/14 测试数据，发布时注释
        try {
            isBroadcastToOtherApp = intent.getBooleanExtra("isBroadcastToOtherApp", false);
        } catch (Exception e) {
            e.printStackTrace();

        }
        setGPSLocation();

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    /**
     * Gets the state of GPS location.
     *
     * @param context
     * @return true if enabled.
     */
    public static boolean getGpsState(Context context) {
        ContentResolver resolver = context.getContentResolver();
        boolean open = Settings.Secure.isLocationProviderEnabled(resolver,
                LocationManager.GPS_PROVIDER);
        System.out.println("getGpsState:" + open);
        return open;
    }

    /**
     * Toggles the state of GPS.
     *
     * @param context
     */
    public static void toggleGps(Context context, boolean enabled) {
        try {
            ContentResolver resolver = context.getContentResolver();
            Settings.Secure.setLocationProviderEnabled(resolver,
                    LocationManager.GPS_PROVIDER, enabled);
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }

    private LocationManager lm;

    /**
     * GPS定位设置
     */
    @SuppressLint("MissingPermission")
    public void setGPSLocation() {
        if (lm == null)
            lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        // 判断GPS是否正常启动
        if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            LogUtil.i(TAG, "GPS未开启");
            //Toast.makeText(this, "请开启GPS导航...", Toast.LENGTH_SHORT).show();
            /*// 返回开启GPS导航设置界面
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivityForResult(intent, 0);*/
            toggleGps(this, true);
            return;
        }

        // 为获取地理位置信息时设置查询条件
        String bestProvider = lm.getBestProvider(GPSUtil.getCriteria(), true);
        // 获取位置信息
        // 如果不设置查询要求，getLastKnownLocation方法传人的参数为LocationManager.GPS_PROVIDER
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        @SuppressLint("MissingPermission") Location location = lm.getLastKnownLocation(bestProvider);
        //updateLocation(location);
        // 监听状态
        lm.addGpsStatusListener(listener);
        // 绑定监听，有4个参数
        // 参数1，设备：有GPS_PROVIDER和NETWORK_PROVIDER两种
        // 参数2，位置信息更新周期，单位毫秒
        // 参数3，位置变化最小距离：当位置距离变化超过此值时，将更新位置信息
        // 参数4，监听
        // 备注：参数2和3，如果参数3不为0，则以参数3为准；参数3为0，则通过时间来定时更新；两者为0，则随时刷新

        // 1秒更新一次，或最小位移变化超过1米更新一次；
        // 注意：此处更新准确度非常低，推荐在service里面启动一个Thread，在run中sleep(10000);然后执行handler.sendMessage(),更新位置
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, locationListener);
    }

    // GPS定位位置监听
    private LocationListener locationListener = new LocationListener() {

        /**
         * 位置信息变化时触发
         */
        @Override
        public void onLocationChanged(Location location) {
            /*long nowTime = new Date().getTime();
            if ((nowTime - location.getTime()) > 3000) {
                return;
            }*/
            updateLocation(location);
            LogUtil.i(TAG, "时间：" + location.getTime());
            LogUtil.i(TAG, "经度：" + location.getLongitude());
            LogUtil.i(TAG, "纬度：" + location.getLatitude());
            LogUtil.i(TAG, "海拔：" + location.getAltitude());
        }

        /**
         * GPS状态变化时触发
         */
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            switch (status) {
                // GPS状态为可见时
                case LocationProvider.AVAILABLE:
                    LogUtil.i(TAG, "当前GPS状态为可见状态");
                    break;
                // GPS状态为服务区外时
                case LocationProvider.OUT_OF_SERVICE:
                    LogUtil.i(TAG, "当前GPS状态为服务区外状态");
                    break;
                // GPS状态为暂停服务时
                case LocationProvider.TEMPORARILY_UNAVAILABLE:
                    LogUtil.i(TAG, "当前GPS状态为暂停服务状态");
                    break;
            }
        }

        /**
         * GPS开启时触发
         */
        @Override
        public void onProviderEnabled(String provider) {
            if (ActivityCompat.checkSelfPermission(GpsService.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    && ActivityCompat.checkSelfPermission(GpsService.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.
                return;
            }
            @SuppressLint("MissingPermission") Location location = lm.getLastKnownLocation(provider);
            //updateLocation(location);
        }

        /**
         * GPS禁用时触发
         */
        @Override
        public void onProviderDisabled(String provider) {
            updateLocation(null);
        }

    };

    // GPS定位状态监听
    GpsStatus.Listener listener = new GpsStatus.Listener() {
        public void onGpsStatusChanged(int event) {
            switch (event) {
                // 第一次定位
                case GpsStatus.GPS_EVENT_FIRST_FIX:
                    LogUtil.i(TAG, "第一次定位");
                    break;
                // 卫星状态改变
                case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
                    LogUtil.i(TAG, "卫星状态改变");
                    // 获取当前状态
                    if (ActivityCompat.checkSelfPermission(GpsService.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                        // TODO: Consider calling
                        //    ActivityCompat#requestPermissions
                        // here to request the missing permissions, and then overriding
                        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                        //                                          int[] grantResults)
                        // to handle the case where the user grants the permission. See the documentation
                        // for ActivityCompat#requestPermissions for more details.
                        return;
                    }
                    @SuppressLint("MissingPermission") GpsStatus gpsStatus = lm.getGpsStatus(null);
                    // 获取卫星颗数的默认最大值
                    int maxSatellites = gpsStatus.getMaxSatellites();
                    // 创建一个迭代器保存所有卫星
                    Iterator<GpsSatellite> iters = gpsStatus.getSatellites()
                            .iterator();
                    int count = 0;
                    while (iters.hasNext() && count <= maxSatellites) {
                        GpsSatellite s = iters.next();
                        count++;
                    }
                    //satelliteTV.setText(count + "");
                    System.out.println("搜索到：" + count + "颗卫星");
                    break;
                // 定位启动
                case GpsStatus.GPS_EVENT_STARTED:
                    LogUtil.i(TAG, "定位启动");
                    break;
                // 定位结束
                case GpsStatus.GPS_EVENT_STOPPED:
                    LogUtil.i(TAG, "定位结束");
                    break;
            }
        }

        ;
    };

    /**
     * GPS定位实时更新
     *
     * @param location
     */

    public static final String key_gps_latitude = "key_gps_latitude";
    public static final String key_gps_longitude = "key_gps_longitude";
    public static final String key_gps_speed = "key_gps_speed";
    public static final String key_gps_gpsTime = "key_gps_gpsTime";
    public static final String key_gps_sysTime = "key_gps_sysTime";

    private void updateLocation(Location location) {
        if (location != null) {
            LogUtil.d(TAG, "location.getLatitude()" + location.getLatitude());
            LogUtil.d(TAG, "location.getLongitude()" + location.getLongitude());
            LogUtil.d(TAG, "location.getSpeed()" + location.getSpeed());
            LogUtil.d(TAG, "location.getTime()" + location.getTime());
            LogUtil.d(TAG, "new Date().getTime()" + new Date().getTime());
            
            PrefUtil.setPrefString(this, "", key_gps_latitude, location.getLatitude() + "");
            PrefUtil.setPrefString(this, "", key_gps_longitude, location.getLongitude() + "");
            PrefUtil.setPrefString(this, "", key_gps_speed, location.getSpeed() + "");
            PrefUtil.setPrefString(this, "", key_gps_gpsTime, location.getTime() + "");
            PrefUtil.setPrefString(this, "", key_gps_sysTime, new Date().getTime() + "");


            EventBus.getDefault().post(new Event(Event.GPS));

        } else {
            LogUtil.d(TAG, "location = null");

        }

    }

    /*public void tran(){
        // 将GPS设备采集的原始GPS坐标转换成百度坐标

        CoordinateConverter converter  = new CoordinateConverter();
        converter.from(CoordType.GPS);

// sourceLatLng待转换坐标

        converter.coord(sourceLatLng);
        LatLng desLatLng = converter.convert();
    }*/

    /**
     * Created by Administrator on 2016/11/28.
     */

    public static class GPSUtil {
        /**
         * GPS定位返回查询条件
         *
         * @return
         */
        public static Criteria getCriteria() {
            Criteria criteria = new Criteria();
            // 设置定位精确度 Criteria.ACCURACY_COARSE比较粗略，Criteria.ACCURACY_FINE则比较精细
            criteria.setAccuracy(Criteria.ACCURACY_FINE);
            // 设置是否要求速度
            criteria.setSpeedRequired(false);
            // 设置是否允许运营商收费
            criteria.setCostAllowed(false);
            // 设置是否需要方位信息
            criteria.setBearingRequired(false);
            // 设置是否需要海拔信息
            criteria.setAltitudeRequired(false);
            // 设置对电源的需求
            criteria.setPowerRequirement(Criteria.POWER_LOW);
            return criteria;
        }
    }

    public static final int GPS_STATE_OK = -100;//坐标过期
    public static final int GPS_STATE_NOT_GET = -101;//未获取到位置坐标
    public static final int GPS_STATE_TIME_PAST = -102;//坐标过期

    /**
     * 检测位置坐标时效性，有效返回 GPS_STATE_OK
     *
     * @param latitude
     * @param longitude
     * @param time
     * @return
     */
    public static int checkGPSTimeliness(String longitude, String latitude, String time, int limitSecond) {
        if (latitude.equals("0") || longitude.equals("0") ||
                TextUtils.isEmpty(latitude) || TextUtils.isEmpty(longitude))
            return GPS_STATE_NOT_GET;
        if (TextUtils.isEmpty(time))
            return GPS_STATE_TIME_PAST;
        long timeI = Long.parseLong(time);
        long timeNow = new Date().getTime();
        if (!((timeNow - timeI) < limitSecond * 1000))
            return GPS_STATE_TIME_PAST;
        return GPS_STATE_OK;
    }


    public static int checkGPSIsNull(String lautitude, String longitude) {
        try {
            double x = Double.valueOf(longitude);
            double y = Double.valueOf(lautitude);

            if (x <= 0 || y <= 0)
                return GPS_STATE_NOT_GET;
        } catch (Exception e) {
            e.printStackTrace();
            return GPS_STATE_NOT_GET;
        }
        return GPS_STATE_OK;
    }

    public static boolean checkGPSIsNullBoolean(String lautitude, String longitude) {
        try {
            double x = Double.valueOf(longitude);
            double y = Double.valueOf(lautitude);

            if (x <= 0 || y <= 0)
                return true;
        } catch (Exception e) {
            e.printStackTrace();
            return true;
        }
        return false;
    }

    public static boolean checkGPSIsNullBoolean(double lautitude, double longitude) {
        if (lautitude <= 0 || longitude <= 0)
            return true;
        return false;
    }

    public static String getLongitude(Context context) {
        return PrefUtil.getPrefString(context, "", key_gps_longitude, "0");

    }

    public static String getLautitude(Context context) {
        return PrefUtil.getPrefString(context, "", key_gps_latitude, "0");

    }

    public static String getSpeed(Context context) {
        return PrefUtil.getPrefString(context, "", key_gps_speed, "0");

    }

    public static String getGpsTime(Context context) {
        return PrefUtil.getPrefString(context, "", key_gps_gpsTime, "0");

    }

    public static String getGpsSysTime(Context context) {
        return PrefUtil.getPrefString(context, "", key_gps_sysTime, "0");

    }
}
